package com.junzhiit.nengji.cms.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bainaeco.framework.util.DateUtil;
import com.junzhiit.nengji.bo.OrdersTransactionInfoBO;
import com.junzhiit.nengji.bo.ShopClientBO;
import com.junzhiit.nengji.cms.service.CouponsService;
import com.junzhiit.nengji.cms.service.ShopClientService;
import com.junzhiit.nengji.cms.web.exception.ClientNotFoundException;
import com.junzhiit.nengji.cms.web.exception.ClientNumberBeyondException;
import com.junzhiit.nengji.cms.web.exception.ClientNumberExistException;
import com.junzhiit.nengji.cms.web.exception.MemberCardNotFoundException;
import com.junzhiit.nengji.cms.web.exception.NotReservedNumberException;
import com.junzhiit.nengji.cms.web.util.ViewObjectUtil;
import com.junzhiit.nengji.cms.web.util.tools.NumberUtils;
import com.junzhiit.nengji.cms.web.vo.DataTablesParamVO;
import com.junzhiit.nengji.cms.web.vo.ReservedVO;
import com.junzhiit.nengji.cms.web.vo.ResultVO;
import com.junzhiit.nengji.cms.web.vo.ShopClientVO;
import com.junzhiit.nengji.cms.web.vo.SystemUserSessionVO;
import com.junzhiit.nengji.dao.BalanceHistoryDAO;
import com.junzhiit.nengji.dao.MemberCardDAO;
import com.junzhiit.nengji.dao.OrdersDAO;
import com.junzhiit.nengji.dao.ShopClientDAO;
import com.junzhiit.nengji.dao.cache.ReservedCacheDAO;
import com.junzhiit.nengji.dao.cache.SystemUserCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.BalanceHistory;
import com.junzhiit.nengji.model.MemberCard;
import com.junzhiit.nengji.model.ShopClient;
import com.junzhiit.nengji.model.enums.BalanceHistoryOperation;
import com.junzhiit.nengji.model.enums.Is;
import com.junzhiit.nengji.model.enums.MemberCardType;
import com.junzhiit.nengji.model.enums.MemberCardValidTime;
import com.junzhiit.nengji.model.enums.MemberLevelCode;
import com.junzhiit.nengji.model.enums.ShopClientStatus;

@Service
public class ShopClientServiceImpl implements ShopClientService{
	
	@Autowired
	private ShopClientDAO shopClientDAO;
	
	@Autowired
	private SystemUserCacheDAO systemUserCacheDAO;
	
	@Autowired
	private MemberCardDAO memberCardDAO;
	
	@Autowired
	private BalanceHistoryDAO balanceHistoryDAO;
	
	@Autowired
	private ReservedCacheDAO reservedCacheDAO;
	
	@Autowired
	private CouponsService couponsService;
	
	@Autowired
	private OrdersDAO ordersDAO;

	@Override
	public ResultVO add(ShopClientVO shopClientVO) {
		ResultVO result = new ResultVO();
		ShopClient shopClient=shopClientDAO.query(shopClientVO.getId());
		
		//如果该客户未拥有会员编号
		if(!StringUtils.isNotBlank(shopClient.getCardNumber())){
			SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
					.getHash(DIYKey.getSessionHashKey(shopClientVO.getSessionId()), SystemUserSessionVO.class);
			
			//检查会员编号是否存在
			ShopClient client = shopClientDAO.findByNumber(systemUserSessionVO.getSystemId(), shopClientVO.getCardNumber());
			if(client != null){
				throw new ClientNumberExistException("该会员编号已存在！请更换会员编号");
			}
			
			//检查会员编号是否超出最大值
			String key = DIYKey.getReservedKey(systemUserSessionVO.getSystemId());
			ReservedVO reservedVO = reservedCacheDAO.getHash(key, ReservedVO.class);
			if(reservedVO == null){
				throw new NotReservedNumberException("您还没预留该会员编号，无法添加该会员！");
			}
			if(Integer.parseInt(shopClientVO.getCardNumber()) >= Integer.parseInt(reservedVO.getMaxValue())){
				throw new ClientNumberBeyondException("该会员编号已超出最大会员编号！请更换会员编号");
			}
			shopClient.setCardNumber(shopClientVO.getCardNumber());
		}
		
		//检查会员卡是否存在
		MemberCard memberCard = memberCardDAO.query(shopClientVO.getMemberCardId());
		if(memberCard == null){
			throw new MemberCardNotFoundException("找不到该会员卡");
		}
		shopClient.setMemberCardId(shopClientVO.getMemberCardId());
		shopClient.setClientStatus(ShopClientStatus.MEMBER.toIntStatus());
		//更改会员时间
		Date date=new Date();
		if(memberCard.getValidTimeState() == MemberCardValidTime.FOREVER.toIntStatus()){
			shopClient.setMemberDate(date);
		}else if(memberCard.getValidTimeState() == MemberCardValidTime.FIXED.toIntStatus()){
			shopClient.setMemberDate(memberCard.getValidStartTime());
			shopClient.setMemberEndDate(memberCard.getValidEndTime());
		}else if(memberCard.getValidTimeState() == MemberCardValidTime.PERIOD.toIntStatus()){
			shopClient.setMemberDate(date);
			shopClient.setMemberEndDate(DateUtil.addDays(date,memberCard.getValidDays()));
		}
		
		shopClientDAO.update(shopClient);
		return result;
	}

	@Override
	public Map<String, Object> findAll(DataTablesParamVO dtp, ShopClientVO shopClientVO) {
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(shopClientVO.getSessionId()), SystemUserSessionVO.class);

		ShopClientBO shopClientBO = new ShopClientBO();
		BeanUtils.copyProperties(shopClientVO, shopClientBO);
		shopClientBO.setCsId(systemUserSessionVO.getSystemId());

		List<ShopClientBO> list = shopClientDAO.findAll(shopClientBO, dtp.getStart(), dtp.getLength());
		int totalCount = shopClientDAO.getTotalCount(shopClientBO);

		return ViewObjectUtil.dataTables(list, dtp.getDraw(), totalCount);
	}

	@Override
	public ResultVO findClientById(String clientId) {
		ResultVO result = new ResultVO();
		ShopClient shopClient = shopClientDAO.query(clientId);
		if(shopClient == null){
			throw new ClientNotFoundException("找不到该客户");
		}
		
		result.setData(shopClient);
		return result;
	}

	@Override
	public ResultVO changeClient(ShopClientVO shopClientVO) {
		MemberCard memberCard =new MemberCard();
		ResultVO result = new ResultVO();
		Date date=new Date();
		ShopClient shopClient=shopClientDAO.query(shopClientVO.getId());
		if(shopClient == null){
			throw new ClientNotFoundException("找不到该客户");
		}
		if(shopClientVO.getMemberCardId() != null){
			memberCard=memberCardDAO.query(shopClientVO.getMemberCardId());
			if(memberCard == null){
				throw new MemberCardNotFoundException("找不到该会员卡");
			}
			//更换了会员卡，更改会员到期时间
			if(shopClient.getMemberCardId() != shopClientVO.getMemberCardId()){
				if(memberCard.getValidTimeState() == MemberCardValidTime.FOREVER.toIntStatus()){
					shopClient.setMemberDate(date);
					shopClient.setMemberEndDate(null);
				}else if(memberCard.getValidTimeState() == MemberCardValidTime.FIXED.toIntStatus()){
					shopClient.setMemberDate(memberCard.getValidStartTime());
					shopClient.setMemberEndDate(memberCard.getValidEndTime());
				}else if(memberCard.getValidTimeState() == MemberCardValidTime.PERIOD.toIntStatus()){
					shopClient.setMemberDate(date);
					shopClient.setMemberEndDate(DateUtil.addDays(date,memberCard.getValidDays()));
				}
			}
		}else{
			shopClient.setMemberEndDate(date);
		}
		
		if(shopClientVO.getClientStatus() == shopClient.getClientStatus() && shopClientVO.getClientStatus() == ShopClientStatus.UNMEMBER.toIntStatus()){
			shopClient.setMemberEndDate(null);
		}
		
		shopClient.setMemberCardId(shopClientVO.getMemberCardId());
		shopClient.setClientStatus(shopClientVO.getClientStatus());
		
		shopClientDAO.update(shopClient,true);
		return result;
	}

	@Override
	public ResultVO memberCharge(ShopClientVO shopClientVO) {
		ResultVO result = new ResultVO();
		//储值更新店铺客户表
		ShopClient shopClient = shopClientDAO.query(shopClientVO.getId());
		if(shopClient == null){
			throw new ClientNotFoundException("找不到该客户");
		}
		shopClient.setBalance(shopClient.getBalance()+shopClientVO.getChargeMoney());
		if(shopClientVO.getIntegral()!=null){
			shopClient.setConsumeIntegral(shopClient.getConsumeIntegral()+shopClientVO.getIntegral());
			shopClient.setNowIntegral(shopClient.getNowIntegral()+shopClientVO.getIntegral());
		}
		shopClientDAO.update(shopClient);
		
		//储值更新储值历史表
		BalanceHistory balanceHistory = new BalanceHistory();
		balanceHistory.setCsId(shopClient.getCsId());
		balanceHistory.setUserId(shopClient.getUserId());
		balanceHistory.setClientId(shopClient.getId());
		balanceHistory.setTransactionNumber(NumberUtils.getMchBillno());
		balanceHistory.setBalanceChange(shopClientVO.getChargeMoney());
		balanceHistory.setOperation(BalanceHistoryOperation.STORAGE_VALUE.toIntValue());
		balanceHistory.setClientId(shopClientVO.getCouponsId());
		balanceHistory.setGiveIntegral(shopClientVO.getIntegral());
		balanceHistory.setStatus(Is.YES.toIntValue());
		balanceHistory.setType(Is.YES.toIntValue());
		if(StringUtils.isNotBlank(shopClientVO.getCouponsId())){
			balanceHistory.setCouponsId(shopClientVO.getCouponsId());
			//插入用户优惠券表
			couponsService.insert(shopClient.getUserId(), shopClientVO.getCouponsId());
		}
		balanceHistoryDAO.insert(balanceHistory);
		
		return result;
	}

	@Override
	public ResultVO setReserved(String sessionId,ReservedVO reservedVO) {
		ResultVO result = new ResultVO();
		
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(sessionId), SystemUserSessionVO.class);
		reservedVO.setMaxValue(reservedVO.getEndValue());
		String key = DIYKey.getReservedKey(systemUserSessionVO.getSystemId());
		reservedCacheDAO.addHash(key, reservedVO);
		
		return result;
	}

	@Override
	public ResultVO findValue(String sessionId) {
		String value="000000";
		ResultVO result = new ResultVO();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO
				.getHash(DIYKey.getSessionHashKey(sessionId), SystemUserSessionVO.class);
		
		String key = DIYKey.getReservedKey(systemUserSessionVO.getSystemId());
		ReservedVO reservedVO = new ReservedVO();
		reservedVO = reservedCacheDAO.getHash(key,ReservedVO.class);
		if(reservedVO != null){
			if(reservedVO.getMaxValue() == null || reservedVO.getMaxValue().isEmpty()){
				reservedVO.setMaxValue(value);
			}
			if(reservedVO.getStartValue() == null || reservedVO.getStartValue().isEmpty()){
				reservedVO.setStartValue(value);
			}
			if(reservedVO.getEndValue() == null || reservedVO.getEndValue().isEmpty()){
				reservedVO.setEndValue(value);
			}
		}
		
		result.setData(reservedVO);
		return result;
	}

	@Override
	public ResultVO giveCoupons(String userId, String couponsId) {
		ResultVO result = new ResultVO();
		couponsService.insert(userId,couponsId);
		return result;
	}

	@Override
	public void updateMemberExpireTime() {
		Date now = new Date();
		//获取该所有店铺所有过期客户信息
		List<ShopClient> shopClient = shopClientDAO.findShopClient();
		//统计用户在该店铺下得消费次数以及消费金额
		OrdersTransactionInfoBO ordersTransactionInfoBO = null;
		//判断是否可以领取会员卡
		boolean receive = false;
		for(ShopClient client : shopClient){
			// 查询出该店铺下得会员卡
			List<MemberCard> memberCardList = memberCardDAO.findAll(client.getCsId());
			//查询出该客户拥有的会员卡
			MemberCard card = memberCardDAO.query(client.getMemberCardId());
			// 如果是最小
			if (client.getGrade() == null || client.getGrade() <= MemberLevelCode.STAIR.toIntValue()) {
				// 如果是购买会员卡失效，则统计相应规则属于哪个按等级发放会员卡标准
				if (card.getType() == MemberCardType.TWO_LEVEL.toIntValue()) {
					ordersTransactionInfoBO = ordersDAO.countUserTransaction(client.getUserId(), client.getCsId(),client.getIsChain(),
							client.getCreatedTime());
					for (int i = 0, t = memberCardList.size(); i < t; i++) {
						MemberCard memberCard = memberCardList.get(i);
						if (memberCard.getType() == MemberCardType.ONE_LEVEL.toIntValue()) {
							if (memberCard.getBuyCount() != null && memberCard.getBuyCount() > 0) {
								// 用户的累积交易次数 大于 该会员卡的可获得的交易次数
								if (ordersTransactionInfoBO.getCountTransaction() > memberCard.getBuyCount()) {
									receive = true;
								} else {
									receive = false;
									continue;
								}
							}
							if (memberCard.getConsumePrice() != null && memberCard.getConsumePrice() > 0) {
								// 用户的累计交易金额 大于 该会员卡的可获得的交易金额数
								if (ordersTransactionInfoBO.getSumPayMoney() != null
										&& ordersTransactionInfoBO.getSumPayMoney() > 0 && ordersTransactionInfoBO
												.getSumPayMoney() > memberCard.getConsumePrice()) {
									receive = true;
								} else {
									receive = false;
									continue;
								}
							}
							if (receive) {
								client.setMemberCardId(memberCard.getId());
								client.setGrade(memberCard.getCardGrade());
								if(memberCard.getValidTimeState() == MemberCardValidTime.FOREVER.toIntStatus()){
									client.setMemberDate(now);
									client.setMemberEndDate(null);
								}else if(memberCard.getValidTimeState() == MemberCardValidTime.FIXED.toIntStatus()){
									client.setMemberDate(memberCard.getValidStartTime());
									client.setMemberEndDate(memberCard.getValidEndTime());
								}else if(memberCard.getValidTimeState() == MemberCardValidTime.PERIOD.toIntStatus()){
									client.setMemberDate(now);
									client.setMemberEndDate(DateUtil.addDays(now,memberCard.getValidDays()));
								}
								shopClientDAO.update(client);
							}
						}
					}
				} else {
					client.setMemberCardId(null);
					client.setGrade(MemberLevelCode.ZERO.toIntValue());
					client.setClientStatus(ShopClientStatus.UNMEMBER.toIntStatus());
					shopClientDAO.update(client);
				}
			} else {
				for (int i = 0, t = memberCardList.size(); i < t; i++) {
					MemberCard memberCard = memberCardList.get(i);
					if (memberCard.getType() == MemberCardType.ONE_LEVEL.toIntValue()) {
						// 不是最小会员卡，则降级
						if (memberCard.getCardGrade() != null && memberCard.getCardGrade() == (client.getGrade() - 1)) {
							client.setMemberCardId(memberCard.getId());
							client.setGrade(memberCard.getCardGrade());
							if(memberCard.getValidTimeState() == MemberCardValidTime.FOREVER.toIntStatus()){
								client.setMemberDate(now);
								client.setMemberEndDate(null);
							}else if(memberCard.getValidTimeState() == MemberCardValidTime.FIXED.toIntStatus()){
								client.setMemberDate(memberCard.getValidStartTime());
								client.setMemberEndDate(memberCard.getValidEndTime());
							}else if(memberCard.getValidTimeState() == MemberCardValidTime.PERIOD.toIntStatus()){
								client.setMemberDate(now);
								client.setMemberEndDate(DateUtil.addDays(now,memberCard.getValidDays()));
							}
							shopClientDAO.update(client);
							break;
						}
					}
				}
			}
		}
	}
}
